package com.tangyuan.answer.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tangyuan.answer.mapper.AnswerCollectMapper;

import com.tangyuan.answer.mapper.AnswerMapper;
import com.tangyuan.answer.mapper.AnswerObjectMapper;
import com.tangyuan.answer.mapper.WrongGradeMapper;
import com.tangyuan.answer.service.*;
import com.tangyuan.common.constant.RedisConstant;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.*;
import com.tangyuan.dto.AnswerCollentDto;
import com.tangyuan.dto.RemoveBojectDto;
import com.tangyuan.feignapis.user.IUserFeignClient;
import com.tangyuan.model.*;
import com.tangyuan.vo.AnswerCollentVo;
import com.tangyuan.vo.AnswerObjectVo;
import com.tangyuan.vo.AnswertopaperVo;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service
public class AnswerServiceImpl implements AnswerService {

    @Autowired
    private AnswerMapper answerMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AnswerCollectMapper answerCollectMapper;
    @Autowired
    private IUserFeignClient userFeignClient;

    @Autowired
    private IAnswerObjectGradeService answerObjectGradeService;

    @Autowired
    private WrongGradeMapper wrongGradeMapper;

    @Autowired
    private IAnswerObjectService answerObjectService;

    @Autowired
    private IAnswertopaperService answertopaperService;

    @Autowired
    private IAnswerCollentService answerCollentService;

    @Override
    public Result addAnswerPicture(String token, MultipartFile file) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        if (user.getId()==null){
            return Result.build(null,ResultCodeEnum.LOGIN_AUTH);
        }
        String url = PictureOSSUtils.upload(file, FileNameUtil.getPngName());
        return Result.ok(url);

      /*  String ocRresult = null;
        try {
            ocRresult = BaiDuOCRUtil.getOCRresult(url);
            String name1 = LocalDateTime.now().toString()+UUID.fastUUID().toString().substring(8).replaceAll("-","")+".png";
            String URL = OSSUtilBase64.uploadBase64String(ocRresult, name1);
            return Result.ok(URL);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }*/
    }

    @Override
    public Result updateAnswer(String token, Long id,Long answerObjectId,Long gradeId,String url) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
        //获取用户
        User user = (User) redisTemplate.opsForValue().get(loginKey);
        if (user.getId() == null) {
            return Result.build(null,ResultCodeEnum.LOGIN_AUTH);
        }
        answerMapper.updateAnswer(id, user.getId(), answerObjectId,gradeId, url);
        AnswerCollent answerCollent = answerMapper.getAnswerById(id);
        return Result.ok(answerCollent);
    }
    @Override
    public Result answerToPaper(String token, MultipartFile file,Long objectId,Long gradeId,String paperUrl) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);

        if (user.getId()==null){
             return Result.build(null,ResultCodeEnum.LOGIN_AUTH);
        }
        if (objectId == null){
            return Result.build(null,ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        LambdaQueryWrapper<AnswerObject> answerObjectWrapper = new LambdaQueryWrapper<>();
        answerObjectWrapper.eq(AnswerObject::getId,objectId);
        AnswerObject answerObjectOne = answerObjectService.getOne(answerObjectWrapper);
        if (!Long.valueOf(answerObjectOne.getUserId()).equals(user.getId()) && answerObjectOne.getUserId() != 0) {
            // 在这里返回错误信息，表示用户无权操作
            return Result.build("你无权操作此学科,请确认后重试", ResultCodeEnum.YOU_HAVE_NO_CHANGE);
        }

        if (paperUrl == null){
            paperUrl = PictureOSSUtils.upload(file, FileNameUtil.getPngName());
        }
        Answertopaper answertopaper = new Answertopaper();
        answertopaper.setUserId(user.getId());
        answertopaper.setObjectId(objectId);
        if (gradeId !=null){
            LambdaQueryWrapper<AnswerObjectGrade> answerObjectGradeWrapper = new LambdaQueryWrapper<>();
            answerObjectGradeWrapper.eq(AnswerObjectGrade::getGradeId,gradeId);
            answerObjectGradeWrapper.eq(AnswerObjectGrade::getAnswerObjectId,objectId);
            answerObjectGradeWrapper.last("limit 1");
            AnswerObjectGrade AnswerObjectGradeOne = answerObjectGradeService.getOne(answerObjectGradeWrapper);
            if (AnswerObjectGradeOne == null){
                return Result.build("你选择的年纪不存在,请确认后重试",ResultCodeEnum.CHOOSE_NOT_EXISTENT);
            }
            answertopaper.setGradeId(gradeId);
        }
        answertopaper.setImage(paperUrl);
        if (file != null){
            try {
                int[] imageDimensions = ImageDimensionUtils.getImageDimensions(file);
                answertopaper.setLSize(imageDimensions[0]);
                answertopaper.setWSize(imageDimensions[1]);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        answertopaperService.save(answertopaper);
        return Result.ok(answertopaper);
    }



    @Override
    public Result getPaperById(String token, Long objectId,Long gradeId,Integer pageNum,Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        if (user.getId()==null){
            return Result.build("", ResultCodeEnum.LOGIN_AUTH);
        }
        List<AnswertopaperVo> list = answerMapper.getPaperById(user.getId(),objectId,gradeId);
        return Result.ok(new PageInfo<>(list));
    }

    @Override
    public Result removePaperById(String token, Long id) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        if (user.getId()==null){
            return Result.build(null,ResultCodeEnum.LOGIN_AUTH);
        }
        Answertopaper answertopaper = answertopaperService.getById(id);
        if (answertopaper == null){
            return Result.build("请选择正确的错题卷子",ResultCodeEnum.NO_DATA);
        }
        if (!answertopaper.getUserId().equals(user.getId())){
            return Result.build("你无权操作此错题卷子,请确认后重试",ResultCodeEnum.YOU_HAVE_NO_CHANGE);
        }
        answerMapper.removePaperById(id);
        return Result.ok();
    }

    @Override
    public Result erasePicture(String token, String eraseUrl) throws IOException {
        User user = CommStatus.getUser(token);
        if (user == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_AUTH);
        }

        String accessToken = (String) redisTemplate.opsForValue().get(RedisConstant.BAIDU_ACCESS_TOKEN_PREFIX);

        if (StringUtils.isEmpty(accessToken)){
            accessToken = BaiDuOCRUtil.getAccessToken();
            redisTemplate.opsForValue().set(RedisConstant.BAIDU_ACCESS_TOKEN_PREFIX,accessToken,RedisConstant.ACCESS_TOKEN_TIMEOUT, TimeUnit.MINUTES);
        }

        String ocRresult = null;
        try {
            ocRresult = BaiDuOCRUtil.getOCRresult(eraseUrl,accessToken);
            if (ocRresult.contains("error_code")){
                JSONObject jsonObject = new JSONObject(ocRresult);
                return Result.build(jsonObject.getString("error_msg"),ResultCodeEnum.BAIDUOCR_ERROR_CODE);
            }
            String name = LocalDateTime.now().toString()+UUID.fastUUID().toString().substring(8).replaceAll("-","")+".png";
            String URL = OSSUtilBase64.uploadBase64String(ocRresult, name);
            Map<String, String> hashMap = new HashMap<>();
            hashMap.put("eraseUrl", URL);
            return Result.ok(hashMap);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }



    @Override
    public Result addAnswer(String token,AnswerCollentDto answerCollentDto)  {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        List<String> list = answerCollentDto.getList();
        List<AnswerCollent> list1 = new ArrayList<>();

        if (answerCollentDto.getAnswerObjectId() == null){
            return Result.build(null,ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        LambdaQueryWrapper<AnswerObject> answerObjectWrapper = new LambdaQueryWrapper<>();
        answerObjectWrapper.eq(AnswerObject::getId,answerCollentDto.getAnswerObjectId());
        AnswerObject answerObjectOne = answerObjectService.getOne(answerObjectWrapper);
        if (!Long.valueOf(answerObjectOne.getUserId()).equals(user.getId()) && answerObjectOne.getUserId() != 0) {
            // 在这里返回错误信息，表示用户无权操作
            return Result.build("你无权操作此学科,请确认后重试", ResultCodeEnum.YOU_HAVE_NO_CHANGE);
        }
        for (String url : list){
            AnswerCollent answerCollent = new AnswerCollent();
            answerCollent.setUserId(user.getId());
            answerCollent.setAnswerObjectId(answerCollentDto.getAnswerObjectId());
            answerCollent.setAnswerImage(url);
            if (answerCollentDto.getGradeId()!=null){
                LambdaQueryWrapper<AnswerObjectGrade> answerObjectGradeWrapper = new LambdaQueryWrapper<>();
                answerObjectGradeWrapper.eq(AnswerObjectGrade::getGradeId,answerCollentDto.getGradeId());
                answerObjectGradeWrapper.eq(AnswerObjectGrade::getAnswerObjectId,answerCollentDto.getAnswerObjectId());
                answerObjectGradeWrapper.last("limit 1");
                AnswerObjectGrade AnswerObjectGradeOne = answerObjectGradeService.getOne(answerObjectGradeWrapper);
                if (AnswerObjectGradeOne == null){
                    return Result.build("你选择的年纪不存在,请确认后重试",ResultCodeEnum.CHOOSE_NOT_EXISTENT);
                }
                answerCollent.setGradeId(answerCollentDto.getGradeId());
            }
            answerCollent.setAnswerName(answerCollentDto.getAnswerName());
            answerCollent.setCreateTime(DateUtil.changeLocalDateTimeToDate(LocalDateTime.now()));
            list1.add(answerCollent);
        }
        answerMapper.addAnswer(list1);
        return Result.ok(list1);
    }

    @Override
    public Result getAnswer(String token, Long id,Long gradeId,Integer pageNum,Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        List<AnswerCollentVo> list = answerMapper.getAnswer(user.getId(),id,gradeId);
        return Result.ok(new PageInfo<>(list));
    }

    @Override
    public Result addAnswerObjectGrade(Long userId, String gradeName, Long answerObjectId) {
        if (userId==null){
            return Result.build(null,ResultCodeEnum.LOGIN_AUTH);
        }
        User user = userFeignClient.getUserById(userId);
        if (user == null){
            return Result.build("未查询到登录信息", ResultCodeEnum.NO_DATA);
        }
        if (StringUtils.isEmpty(gradeName)&& answerObjectId == null){
            return Result.build(null,ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        LambdaQueryWrapper<WrongGrade> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(WrongGrade::getName,gradeName);
        lambdaQueryWrapper.eq(WrongGrade::getUserId,userId);
        lambdaQueryWrapper.last("limit 1");
        WrongGrade wrongGrade = wrongGradeMapper.selectOne(lambdaQueryWrapper);

        AnswerObjectGrade answerObjectGrade = new AnswerObjectGrade();
        if (wrongGrade !=null){
            LambdaQueryWrapper<AnswerObjectGrade> answerObjectWrapper = new LambdaQueryWrapper<>();
            answerObjectWrapper.eq(AnswerObjectGrade::getAnswerObjectId,answerObjectId);
            answerObjectWrapper.eq(AnswerObjectGrade::getGradeId,wrongGrade.getId());
            answerObjectWrapper.last("limit 1");
            AnswerObjectGrade answerObjectGradeOne = answerObjectGradeService.getOne(answerObjectWrapper);
            if (answerObjectGradeOne != null){
                return Result.build("你已经创建过此年级，请勿重复创建",ResultCodeEnum.CREATED_THE_SAME);
            }

            answerObjectGrade.setGradeId(wrongGrade.getId());
            answerObjectGrade.setAnswerObjectId(answerObjectId);
            answerObjectGradeService.save(answerObjectGrade);
            return Result.ok(wrongGrade);
        }else{
            WrongGrade wrongGradeInsert = new WrongGrade();
            wrongGradeInsert.setCreateTime(new Date());
            wrongGradeInsert.setUserId(userId);
            wrongGradeInsert.setName(gradeName);
            wrongGradeInsert.setUpdateTime(new Date());
            wrongGradeInsert.setUpdateBy(user.getName());
            wrongGradeMapper.insert(wrongGradeInsert);

            answerObjectGrade.setGradeId(wrongGradeInsert.getId());
            answerObjectGrade.setAnswerObjectId(answerObjectId);
            answerObjectGradeService.save(answerObjectGrade);
            return Result.ok(wrongGradeInsert);
        }
    }

    @Override
    public Result addObject(String token, String name) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        AnswerObject answerObject = answerMapper.getObjectByName(user.getId(),name);
        if (null!=answerObject){
            return Result.build("科目已存在",ResultCodeEnum.OBJECT_EXIST);
        }
        answerMapper.addObject(user.getId(),name,DateUtil.changeLocalDateTimeToDate(LocalDateTime.now()));
        AnswerObject answerObject1 = answerMapper.getObjectByName(user.getId(),name);
        return Result.ok(answerObject1);
    }

    @Override
    public Result getObject(String token) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        List<AnswerObjectVo> list =  answerMapper.getObject(user.getId());
        for (AnswerObjectVo answerObjectVo : list) {
            answerObjectVo.setAnswernum(answerMapper.getAnswerNum(user.getId(),answerObjectVo.getId()));
        }
        return Result.ok(list);
    }


    @Override
    public Result removeObject(String token, RemoveBojectDto removeBojectDto) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
        //获取用户
        User user = (User) redisTemplate.opsForValue().get(loginKey);

        if (user == null) {
            return Result.build("未查询到登录信息", ResultCodeEnum.LOGIN_AUTH);
        }
        if (CollectionUtil.isEmpty(removeBojectDto.getList())){
            return Result.build("请选择要删除的科目",ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }
        LambdaQueryWrapper<AnswerObject> answerObjectWrapper = new LambdaQueryWrapper<>();
        answerObjectWrapper.in(AnswerObject::getId, removeBojectDto.getList());
        List<AnswerObject> answerObjectList = answerObjectService.list(answerObjectWrapper);
        if (CollectionUtil.isEmpty(answerObjectList)) {
            return Result.build("你选择的科目不存在,请确认后重试", ResultCodeEnum.CHOOSE_NOT_EXISTENT);
        }
        boolean containsNonCurrentUser = answerObjectList.stream()
                .anyMatch(answerObject -> !Long.valueOf(answerObject.getUserId()).equals(user.getId()));

        if (containsNonCurrentUser) {
            return Result.build("存在不属于当前用户的科目，请确认后重试", ResultCodeEnum.YOU_HAVE_NO_CHANGE);
        }

        LambdaQueryWrapper<AnswerObjectGrade> answerObjectGradeWrapper = new LambdaQueryWrapper<>();
        answerObjectGradeWrapper.in(AnswerObjectGrade::getAnswerObjectId, removeBojectDto.getList());
        List<AnswerObjectGrade> answerObjectGradeList = answerObjectGradeService.list(answerObjectGradeWrapper);
        List<Long> gradeIdS = answerObjectGradeList.stream().map(answerObjectGrade -> answerObjectGrade.getGradeId()).collect(Collectors.toList());

        LambdaQueryWrapper<AnswerCollent> answerCollentWrapper = new LambdaQueryWrapper<>();
        answerCollentWrapper.in(AnswerCollent::getAnswerObjectId, removeBojectDto.getList());
        if (!CollectionUtil.isEmpty(gradeIdS)){
            answerCollentWrapper.in(AnswerCollent::getGradeId, gradeIdS);
        }
        answerCollentWrapper.eq(AnswerCollent::getUserId, user.getId());
        answerCollentWrapper.eq(AnswerCollent::getIsDelete, 0);
        List<AnswerCollent> answerCollentlist = answerCollentService.list(answerCollentWrapper);
        if (!CollectionUtil.isEmpty(answerCollentlist)) {
            return Result.build("错题未全部删除,删除失败", ResultCodeEnum.ANSWER_IS_NOT_NULL);
        }

        LambdaQueryWrapper<Answertopaper> answertopaperWrapper = new LambdaQueryWrapper<>();
        answertopaperWrapper.in(Answertopaper::getObjectId, removeBojectDto.getList());
        if (!CollectionUtil.isEmpty(gradeIdS)){
            answertopaperWrapper.in(Answertopaper::getGradeId, gradeIdS);
        }
        answertopaperWrapper.eq(Answertopaper::getUserId, user.getId());
        answertopaperWrapper.eq(Answertopaper::getIsDelete, 0);
        List<Answertopaper> answertopaperlist = answertopaperService.list(answertopaperWrapper);
        if (!CollectionUtil.isEmpty(answertopaperlist)) {
            return Result.build("试卷未全部删除,删除失败", ResultCodeEnum.ANSWER_IS_NOT_NULL);
        }

        LambdaQueryWrapper<AnswerObjectGrade> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(AnswerObjectGrade::getAnswerObjectId, removeBojectDto.getList());
        answerObjectGradeService.remove(lambdaQueryWrapper);
        answerMapper.removeObject(user.getId(), removeBojectDto.getList());
        return Result.ok();
    }

    @Override
    public Result serAnswerName(String token, String name,Long id) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        if (user == null) {
            return Result.build(null, ResultCodeEnum.LOGIN_AUTH);
        }
        AnswerCollent answerCollent = answerCollectMapper.selectById(id);
        if (answerCollent == null){
            return Result.build(null,ResultCodeEnum.ARGUMENT_VALID_ERROR);
        }

        if (!answerCollent.getUserId().equals(user.getId())){
            return Result.build(null,ResultCodeEnum.YOU_HAVE_NO_CHANGE);
        }
        answerCollent.setAnswerName(name);
        int i = answerCollectMapper.updateById(answerCollent);
        if (i==0){
            return Result.build(null,ResultCodeEnum.FAIL);
        }
        return Result.ok();
    }

    @Override
    public Result removeAnswerName(String token, Long id) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        if (user == null){
            return Result.build(null,ResultCodeEnum.LOGIN_AUTH);
        }
        AnswerCollent answerCollent = answerCollentService.getById(id);
        if (!answerCollent.getUserId().equals(user.getId())){
            return Result.build(null, ResultCodeEnum.YOU_HAVE_NO_CHANGE);
        }
        answerMapper.removeAnswerName(user.getId(),id);
        return Result.ok();
    }

    @Override
    public Result getFirstObject(String token) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        // 检查user是否为空
        if (user == null || user.getId() == null) {
            return Result.build(null,ResultCodeEnum.FAIL_LOGIN);
        }

        //查询0默认分类
        List<AnswerObjectVo> AnswerObjectList = answerMapper.getFirstObjectByUserId(user.getId());

        for (AnswerObjectVo answerObjectVo : AnswerObjectList){
            answerObjectVo.setIconId(answerObjectVo.getId());
        }

        return Result.ok(AnswerObjectList);
    }

    @Override
    public Result getAllObject(String token) {
        String loginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
        //获取用户
        User user= (User)redisTemplate.opsForValue().get(loginKey);
        // 检查user是否为空
        if (user == null || user.getId() == null) {
            return Result.build(null,ResultCodeEnum.FAIL_LOGIN);
        }
        //根据用户获取所有分类
        List<AnswerObjectVo> AnswerObjectList = answerMapper.getAllObjectByUserId(user.getId());

        for (AnswerObjectVo answerObjectVo : AnswerObjectList){
            answerObjectVo.setIconId(answerObjectVo.getId());
        }
        return Result.ok(AnswerObjectList);
    }
}
